<?php

namespace common\service\export_business_excel_logic;

use common\model\TaskModel;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use support\SingletonTrait;
use common\model\StatusModel;
use common\model\EntityModel;
use common\model\ProjectModel;
use common\service\StatusService;
use common\model\NoteEntityRelationModel;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

/**
 * 镜头表导出
 */
class ShotList implements ExportLogicInterface
{
    use SingletonTrait;

    /**
     * @param $param
     * @return Spreadsheet
     * @throws \think\Exception
     */
    function process($param): Spreadsheet
    {
        $spreadsheet = new Spreadsheet();

        $project = model(ProjectModel::class)->find($param['project_id']);
        $episode = model(EntityModel::class)->find($param['episode_id']);

        $worksheet = $spreadsheet->getActiveSheet();
        $worksheet->mergeCellsByColumnAndRow(1, 1, 16, 1);

        $worksheet->setCellValueByColumnAndRow(1, 1, "《{$project['name']}》{$episode['name']}镜头表");
        $worksheet->getStyleByColumnAndRow(1, 1, 16, 1)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);

        $storyboardModuleId = module_by_code('storyboard')['id'];
        $doneStatus = StatusService::getInstance()->getTaskDoneStatus();
        $inprogressStatus = StatusService::getInstance()->getTaskDefaultStartStatus();
        $closedStatus = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $shotCount = model(EntityModel::class)->query("SELECT
            count( id ) total,
            count( json ->> '$.storyboard_status' = {$doneStatus['id']} OR NULL ) done,
            count( json ->> '$.storyboard_status' = {$inprogressStatus['id']} OR NULL ) inprogress,
            count(json->>'$.storyboard_status'= {$closedStatus['id']} or null) closed
        FROM
            entity 
        WHERE
            project_id = {$project['id']} 
            AND initial_episode_code = '{$episode['code']}' 
            AND module_id = {$storyboardModuleId}"
        );
        $shotCount = $shotCount[0];
        $worksheet->mergeCellsByColumnAndRow(1, 2, 16, 2);

        $worksheet->setCellValueByColumnAndRow(1, 2, "共计:{$shotCount['total']}镜头  已完成: {$shotCount['done']}镜头  进行中: {$shotCount['inprogress']}镜头  已废除: {$shotCount['closed']}镜头");
        $dataColumns = [
            [
                's' => 1,
                'e' => 4,
                'name' => '镜头信息',
                'step_category_id' => 0,
                'sub_col' => [
                    '集',
                    '场',
                    '镜',
                    '资产关联信息',
                ],
            ], [
                's' => 5,
                'e' => 7,
                'name' => '动画',
                'step_category_id' => 41,
                'sub_col' => [
                    '是否有需求备注',
                    '任务状态',
                    '完成时间',
                ],
            ], [
                's' => 8,
                'e' => 10,
                'name' => '解算',
                'step_category_id' => 42,
                'sub_col' => [
                    '是否有需求备注',
                    '任务状态',
                    '完成时间',
                ],
            ], [
                's' => 11,
                'e' => 13,
                'name' => '灯光',
                'step_category_id' => 17,
                'sub_col' => [
                    '是否有需求备注',
                    '任务状态',
                    '完成时间',
                ],
            ], [
                's' => 14,
                'e' => 16,
                'name' => '特效',
                'step_category_id' => 18,
                'sub_col' => [
                    '是否有需求备注',
                    '任务状态',
                    '完成时间',
                ],
            ],

        ];

        $currentRow = 3;
        foreach ($dataColumns as $column) {
            $worksheet->mergeCellsByColumnAndRow($column['s'], $currentRow, $column['e'], $currentRow);
            $worksheet->setCellValueByColumnAndRow($column['s'], $currentRow, $column['name']);
            $worksheet->getStyleByColumnAndRow($column['s'], $currentRow, $column['e'], $currentRow)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
            $columnIndex = $column['s'];
            foreach ($column['sub_col'] as $subColName) {
                $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow + 1, $subColName);
                $worksheet->getStyleByColumnAndRow($columnIndex, $currentRow + 1, $columnIndex, $currentRow + 1)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
                $columnIndex += 1;
            }
        }
        $currentRow += 2;

        $episodeShotListFilter = [
            'project_id' => $project['id'],
            'initial_episode_code' => $episode['code'],
            'module_id' => module_by_code('shot')['id'],
        ];
        // 镜头列表
        $episodeShotList = model(EntityModel::class)
            ->where($episodeShotListFilter)
            ->select();

        if (empty($episodeShotList)) {
            return $spreadsheet;
        }

        $relateAssetLevelIdList = [];
        // 关联资产、关卡查询
        foreach ($episodeShotList as &$shot) {
            $shot['json'] = json_decode($shot['json'], true);
            $shot['relate_asset_level'] = [];
            if (!empty($shot['json']['shot_level'])) {
                foreach (explode(',', $shot['json']['shot_level']) as $levelId) {
                    if (!in_array($levelId, $shot['relate_asset_level'])) {
                        $shot['relate_asset_level'][] = $levelId;
                    }
                }
            }
            if (!empty($shot['json']['shot_asset'])) {
                foreach (explode(',', $shot['json']['shot_asset']) as $assetId) {
                    if (!in_array($assetId, $shot['relate_asset_level'])) {
                        $shot['relate_asset_level'][] = $assetId;
                    }
                }
            }
            foreach ($shot['relate_asset_level'] as $assetLevelId) {
                if (!in_array($assetLevelId, $relateAssetLevelIdList)) {
                    $relateAssetLevelIdList[] = $assetLevelId;
                }
            }
        }
        $relateAssetLevelList = [];
        if (!empty($relateAssetLevelIdList)) {
            $relateAssetLevelList = model(EntityModel::class)->field('id,name')->where(['id' => ['IN', $relateAssetLevelIdList]])->select();
            $relateAssetLevelList = array_column($relateAssetLevelList, 'name', 'id');
        }


        // 镜头需求列表
        $shotNoteListFilter = [
            'project_id' => $project['id'],
            'relate_module_code' => 'shot',
            'episode_code' => $episode['code'],
        ];
        $shotNoteList = [];
//        $shotNoteList = model(NoteEntityRelationModel::class)
//            ->where($shotNoteListFilter)
//            ->group('relation_type, entity_id, step_category_id')
//            ->select();

        $episodeNote = false;
        $entityNote = [];
        $entityStepCategoryNote = [];
        foreach ($shotNoteList as $shotNote) {
            switch ($shotNote['relation_type']) {
                case 'episode':
                    $episodeNote = true;
                    break;
                case 'entity':
                    $entityNote[] = $shotNote['entity_id'];
                    break;
                case 'step_category':
                case 'step':
                    $entityStepCategoryNote[$shotNote['entity_id'] . '#' . $shotNote['step_category_id']] = true;
                    break;
            }
        }


        $shotIds = implode(',', array_column($episodeShotList, 'id'));
        // 镜头任务完成情况
        $shotTaskList = model(TaskModel::class)
            ->where("id in (select max(id) from task where project_id = {$project['id']} and step_type='step' and entity_id in ({$shotIds}) group by entity_id,step_category_id )")
            ->field('entity_id,step_category_id,end_time,json,concat(entity_id,"#",step_category_id) as unique_id')
            ->select();
        $shotTaskList = array_column($shotTaskList, null, 'unique_id');

        unset($shot);
        $statusList = model(StatusModel::class)->select();
        $statusList = array_column($statusList, 'name', 'id');
        foreach ($episodeShotList as $shot) {
            $columnIndex = 1;
            foreach ($dataColumns as $column) {
                if ($column['step_category_id'] <= 0) {
                    if ($column['name'] === '镜头信息') {
                        $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $shot['initial_episode_code']);
                        $columnIndex += 1;
                        $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $shot['showings_number']);
                        $columnIndex += 1;
                        $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $shot['name']);
                        $columnIndex += 1;
                        $relateName = '';
                        if (!empty($shot['relate_asset_level'])) {
                            foreach ($shot['relate_asset_level'] as $relateAssetLevelId) {
                                if (isset($relateAssetLevelList[$relateAssetLevelId])) {
                                    $relateName .= ',' . $relateAssetLevelList[$relateAssetLevelId];
                                }
                            }
                            $relateName = trim($relateName, ',');
                        }
                        $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $relateName);
                        $columnIndex += 1;
                    }
                } else {
                    $hasNote = false;
                    $shotStoryboard = $shot['json']['shot_storyboard'] ?? 0;
                    if ($shotStoryboard <= 0) {
                        $hasNote = false;
                    } elseif ($episodeNote) {
                        $hasNote = true;
                    } elseif (!empty($entityNote[$shotStoryboard])) {
                        $hasNote = true;
                    } elseif (!empty($entityStepCategoryNote[$shotStoryboard . '#' . $column['step_category_id']])) {
                        $hasNote = true;
                    }
                    $entityStepCategoryTask = $shotTaskList[$shot['id'] . '#' . $column['step_category_id']] ?? null;
                    $taskStatus = '-';
                    $doneTime = '-';
                    if (!empty($entityStepCategoryTask)) {
                        $entityStepCategoryTask['json'] = json_decode($entityStepCategoryTask['json'], true);
                        if (!empty($statusList[$entityStepCategoryTask['json']['task_status'] ?? 0])) {
                            $taskStatus = $statusList[$entityStepCategoryTask['json']['task_status']];
                        }
                        if ($entityStepCategoryTask['end_time'] > 0) {
                            $doneTime = date("Y\\\m\\\d", $entityStepCategoryTask['end_time']);
                        }
                    }
                    $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $hasNote ? '是' : '否');
                    $columnIndex += 1;
                    $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $taskStatus);
                    $columnIndex += 1;
                    $worksheet->setCellValueByColumnAndRow($columnIndex, $currentRow, $doneTime);
                    $columnIndex += 1;
                }
            }
            $currentRow += 1;
        }
        return $spreadsheet;
    }
}
